<div class="tmd-doc">
<h1 class="tmd-header-1">
Methods in Go
</h1>
<p></p>
<div class="tmd-usual">
Go supports some object-orient programming features. Method is one of these features. This article will introduce method related concepts in Go.
</div>
<p></p>
<h3 class="tmd-header-3">
Method Declarations
</h3>
<p></p>
<div class="tmd-usual">
In Go, we can (explicitly) declare a method for type <code class="tmd-code-span">T</code> and <code class="tmd-code-span">*T</code>, where <code class="tmd-code-span">T</code> must satisfy 4 conditions:
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
<code class="tmd-code-span">T</code> must be a <a href="type-system-overview.html#type-definition">defined type</a>;
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
<code class="tmd-code-span">T</code> must be defined in the same package as the method declaration;
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
<code class="tmd-code-span">T</code> must not be a pointer type;
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
<code class="tmd-code-span">T</code> must not be an interface type. Interface types will be explained in <a href="interface.html">the next article</a>.
</div>
</li>
</ol>
<p></p>
<p></p>
<div class="tmd-usual">
Type <code class="tmd-code-span">T</code> and <code class="tmd-code-span">*T</code> are called the receiver type of the respective methods declared for them. Type <code class="tmd-code-span">T</code> is called the receiver base types of all methods declared for both type <code class="tmd-code-span">T</code> and <code class="tmd-code-span">*T</code>.
</div>
<p></p>
<div class="tmd-usual">
Note, we can also declare methods for <a href="type-system-overview.html#type-alias">type aliases</a> of the <code class="tmd-code-span">T</code> and <code class="tmd-code-span">*T</code> types specified above. The effect is the same as declaring methods for the <code class="tmd-code-span">T</code> and <code class="tmd-code-span">*T</code> types themselves.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
If a method is declared for a type, we can say the type has (or owns) the method.
</div>
<p></p>
<div class="tmd-usual">
From the above listed conditions, we will get the conclusions that we can never (explicitly) declare methods for:
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
predeclared types, such as <code class="tmd-code-span">int</code> and <code class="tmd-code-span">string</code>, for we can't declare methods in the <code class="tmd-code-span">builtin</code> standard package.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
interface types. But an interface type can own methods. Please read <a href="interface.html">the next article</a> for details.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
<a href="type-system-overview.html#named-type">unnamed types</a>. except the pointer types with the form <code class="tmd-code-span">*T</code> which are described above.
</div>
</li>
</ul>
<p></p>
<p></p>
<div class="tmd-usual">
A method declaration is similar to a function declaration, but it has an extra parameter declaration part. The extra parameter part can contain one and only one parameter of the receiver type of the method. The only one parameter is called a receiver parameter of the method declaration. The receiver parameter must be enclosed in a <code class="tmd-code-span">()</code> and declared between the <code class="tmd-code-span">func</code> keyword and the method name.
</div>
<p></p>
<div class="tmd-usual">
Here are some method declaration examples:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">// Age and int are two distinct types. We
// can't declare methods for int and *int,
// but can for Age and *Age.
type Age int
func (age Age) LargerThan(a Age) bool {
	return age &gt; a
}
func (age *Age) Increase() {
	*age++
}

// Receiver of custom defined function type.
type FilterFunc func(in int) bool
func (ff FilterFunc) Filte(in int) bool {
	return ff(in)
}

// Receiver of custom defined map type.
type StringSet map[string]struct{}
func (ss StringSet) Has(key string) bool {
	_, present := ss[key]
	return present
}
func (ss StringSet) Add(key string) {
	ss[key] = struct{}{}
}
func (ss StringSet) Remove(key string) {
	delete(ss, key)
}

// Receiver of custom defined struct type.
type Book struct {
	pages int
}

func (b Book) Pages() int {
	return b.pages
}

func (b *Book) SetPages(pages int) {
	b.pages = pages
}
</code></pre>
<p></p>
<div class="tmd-usual">
From the above examples, we know that the receiver base types not only can be struct types, but also can be other kinds of types, such as basic types and container types, as long as the receiver base types satisfy the 4 conditions listed above.
</div>
<p></p>
<div class="tmd-usual">
In some other programming languages, the receiver parameter names are always the implicit <code class="tmd-code-span">this</code>, which is not a recommended identifier for receiver parameter names in Go.
</div>
<p></p>
<div class="tmd-usual">
The receiver of type <code class="tmd-code-span">*T</code> is called <span class="tmd-bold"><span class="tmd-italic">pointer receiver</span></span>, non-pointer receivers are called <span class="tmd-bold"><span class="tmd-italic">value receivers</span></span>. Personally, I don't recommend to view the terminology <span class="tmd-bold"><span class="tmd-italic">pointer</span></span> as an opposite of the terminology <span class="tmd-bold"><span class="tmd-italic">value</span></span>, because pointer values are just special values. But, I am not against using the pointer receiver and value receiver terminologies here. The reason will be explained below.
</div>
<p></p>
<div class="tmd-usual">
Method names can be the blank identifier <code class="tmd-code-span">_</code>. A type can have multiple methods with the blank identifier as name. But such methods can never be called. Only exported methods can be called from other packages. Method calls will be introduced in a later section.
</div>
<p></p>
<h3 id="method-as-function" class="tmd-header-3">
Each Method Corresponds to an Implicit Function
</h3>
<p></p>
<div class="tmd-usual">
For each method declaration, compiler will declare a corresponding implicit function for it. For the last two methods declared for type <code class="tmd-code-span">Book</code> and type <code class="tmd-code-span">*Book</code> in the last example in the last section, two following functions are implicitly declared by compiler:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func Book.Pages(b Book) int {
	// The body is the same as the Pages method.
	return b.pages
}

func (*Book).SetPages(b *Book, pages int) {
	// The body is the same as the SetPages method.
	b.pages = pages
}
</code></pre>
<p></p>
<div class="tmd-usual">
In each of the two implicit function declarations, the receiver parameter is removed from its corresponding method declaration and inserted into the normal parameter list as the first one. The function bodies of the two implicitly declared functions is the same as their corresponding method explicit bodies.
</div>
<p></p>
<div class="tmd-usual">
The implicit function names, <code class="tmd-code-span">Book.Pages</code> and <code class="tmd-code-span">(*Book).SetPages</code>, are both of the form <code class="tmd-code-span">TypeDenotation.MethodName</code>. As identifiers in Go can't contain the period special characters, the two implicit function names are not legal identifiers, so the two functions can't be declared explicitly. They can only be declared by compilers implicitly, but they can be called in user code:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

type Book struct {
	pages int
}

func (b Book) Pages() int {
	return b.pages
}

func (b *Book) SetPages(pages int) {
	b.pages = pages
}

func main() {
	var book Book
	// Call the two implicit declared functions.
	(*Book).SetPages(&amp;book, 123)
	fmt.Println(Book.Pages(book)) // 123
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, compilers not only declare the two implicit functions, they also rewrite the two corresponding explicit declared methods to let the two methods call the two implicit functions in the method bodies (at least, we can think this happens), just like the following code shows:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func (b Book) Pages() int {
	return Book.Pages(b)
}

func (b *Book) SetPages(pages int) {
	(*Book).SetPages(b, pages)
}
</code></pre>
<p></p>
<h3 id="implicit-pointer-methods" class="tmd-header-3">
Implicit Methods With Pointer Receivers
</h3>
<p></p>
<div class="tmd-usual">
For each method declared for value receiver type <code class="tmd-code-span">T</code>, a corresponding method with the same name will be implicitly declared by compiler for type <code class="tmd-code-span">*T</code>. By the example above, the <code class="tmd-code-span">Pages</code> method is declared for type <code class="tmd-code-span">Book</code>, so a method with the same name <code class="tmd-code-span">Pages</code> is implicitly declared for type <code class="tmd-code-span">*Book</code>:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">// Note: this is not a legal Go syntax.
// It is shown here just for explanation purpose.
// It indicates that the expression (&amp;aBook).Pages
// is evaluated as aBook.Pages (see below sections).
func (b *Book) Pages = (*b).Pages
</code></pre>
<p></p>
<div class="tmd-usual">
This is why I don't reject the use of the value receiver terminology (as the opposite of the pointer receiver terminology). After all, when we explicitly declare a method for a non-pointer type, in fact two methods are declared, the explicit one is for the non-pointer type and the implicit one is for the corresponding pointer type.
</div>
<p></p>
<div class="tmd-usual">
As mentioned at the last section, for each declared method, compilers will also declare a corresponding implicit function for it. So for the implicitly declared method, the following implicit function is declared by compiler.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func (*Book).Pages(b *Book) int {
	return Book.Pages(*b)
}
</code></pre>
<p></p>
<div class="tmd-usual">
In other words, for each explicitly declared method with a value receiver, two implicit functions and one implicit method will also be declared at the same time.
</div>
<p></p>
<h3 id="method-set" class="tmd-header-3">
Method Specifications and Method Sets
</h3>
<p></p>
<div class="tmd-usual">
A method specification can be viewed as a <a href="function.html#prototype">function prototype</a> without the <code class="tmd-code-span">func</code> keyword. We can view each method declaration is composed of the <code class="tmd-code-span">func</code> keyword, a receiver parameter declaration, a method specification and a method (function) body.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
For example, the method specifications of the <code class="tmd-code-span">Pages</code> and <code class="tmd-code-span">SetPages</code> methods shown above are
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">Pages() int
SetPages(pages int)
</code></pre>
<p></p>
<div class="tmd-usual">
Each type has a method set. The method set of a non-interface type is composed of all the method specifications of the methods declared, either explicitly or implicitly, for the type, except the ones whose names are the blank identifier <code class="tmd-code-span">_</code>. Interface types will be explained in <a href="interface.html">the next article</a>.
</div>
<p></p>
<div class="tmd-usual">
For example, the method sets of the <code class="tmd-code-span">Book</code> type shown in the previous sections is
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">Pages() int
</code></pre>
<p></p>
<div class="tmd-usual">
and the method set of the <code class="tmd-code-span">*Book</code> type is
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">Pages() int
SetPages(pages int)
</code></pre>
<p></p>
<div class="tmd-usual">
The order of the method specifications in a method set is not important for the method set.
</div>
<p></p>
<div class="tmd-usual">
For a method set, if every method specification in it is also in another method set, then we say the former method set is a subset of the latter one, and the latter one is a superset of the former one. If two method sets are subsets (or supersets) of each other, then we say the two method sets are identical.
</div>
<p></p>
<div class="tmd-usual">
Given a type <code class="tmd-code-span">T</code>, assume it is neither a pointer type nor an interface type, for <a href="#implicit-pointer-methods">the reason</a> mentioned in the last section, the method set of a type <code class="tmd-code-span">T</code> is always a subset of the method set of type <code class="tmd-code-span">*T</code>. For example, the method set of the <code class="tmd-code-span">Book</code> type shown above is a subset of the method set of the <code class="tmd-code-span">*Book</code> type.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Please note, <span class="tmd-bold">non-exported method names, which start with lower-case letters, from different packages will be always viewed as two different method names, even if the two method names are the same in literal.</span>
</div>
<p></p>
<div class="tmd-usual">
Method sets play an important role in the polymorphism feature of Go. About polymorphism, please read <a href="interface.html">the next article</a> (interfaces in Go) for details.
</div>
<p></p>
<div class="tmd-usual">
The method sets of the following types are always blank:
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
built-in basic types.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
defined pointer types.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
pointer types whose base types are interface or pointer types.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
unnamed array, slice, map, function and channel types.
</div>
</li>
</ul>
<p></p>
<h3 id="call" class="tmd-header-3">
Method Values and Method Calls
</h3>
<p></p>
<div class="tmd-usual">
Methods are special functions actually. Methods are often called member functions. When a type owns a method, each value of the type will own an immutable member of a function type. The member name is the same as the method name and the type of the member is the same as the function declared with the form of the method declaration but without the receiver part.
</div>
<p></p>
<div class="tmd-usual">
A method call is just a call to such a member function. For a value <code class="tmd-code-span">v</code>, its method <code class="tmd-code-span">m</code> can be represented with the selector form <code class="tmd-code-span">v.m</code>, which is a function value.
</div>
<p></p>
<div class="tmd-usual">
An example containing some method calls:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

type Book struct {
	pages int
}

func (b Book) Pages() int {
	return b.pages
}

func (b *Book) SetPages(pages int) {
	b.pages = pages
}

func main() {
	var book Book

	fmt.Printf("%T \n", book.Pages)       // func() int
	fmt.Printf("%T \n", (&amp;book).SetPages) // func(int)
	// &amp;book has an implicit method.
	fmt.Printf("%T \n", (&amp;book).Pages) // func() int

	// Call the three methods.
	(&amp;book).SetPages(123)
	book.SetPages(123) // equivalent to the last line
	fmt.Println(book.Pages())    // 123
	fmt.Println((&amp;book).Pages()) // 123
}
</code></pre>
<p></p>
<p></p>
<div class="tmd-usual">
<span class="tmd-italic">(Different from C language, there is not the <code class="tmd-code-span">-&gt;</code> operator in Go to call methods with pointer receivers, so <code class="tmd-code-span">(&amp;book)-&gt;SetPages(123)</code> is illegal in Go.)</span>
</div>
<p></p>
<div class="tmd-usual">
Wait! Why does the line <code class="tmd-code-span">book.SetPages(123)</code> in the above example compile okay? After all, the method <code class="tmd-code-span">SetPages</code> is not declared for the <code class="tmd-code-span">Book</code> type. On one hand, this can be viewed as a syntactic sugar to make programming convenient. This sugar only works for addressable value receivers. Compiler will implicitly take the address of the addressable value <code class="tmd-code-span">book</code> when it is passed as the receiver argument of a <code class="tmd-code-span">SetPages</code> method call. On the other hand, we should also think <code class="tmd-code-span">aBookExpression.SetPages</code> is always a legal selector (from the syntax view), even if the expression <code class="tmd-code-span">aBookExpression</code> is evaluated as an unaddressable <code class="tmd-code-span">Book</code> value, for which case, the selector <code class="tmd-code-span">aBookExpression.SetPages</code> is invalid (but legal).
</div>
<p></p>
<p></p>
<p></p>
<div class="tmd-usual">
As above just mentioned, when a method is declared for a type, each value of the type will own a member function. Zero values are not exceptions, whether or not the zero values of the types are represented by <code class="tmd-code-span">nil</code>.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

type StringSet map[string]struct{}
func (ss StringSet) Has(key string) bool {
	// Never panic here, even if ss is nil.
	_, present := ss[key]
	return present
}

type Age int
func (age *Age) IsNil() bool {
	return age == nil
}
func (age *Age) Increase() {
	*age++ // If age is a nil pointer, then
	       // dereferencing it will panic.
}

func main() {
	_ = (StringSet(nil)).Has   // will not panic
	_ = ((*Age)(nil)).IsNil    // will not panic
	_ = ((*Age)(nil)).Increase // will not panic

	_ = (StringSet(nil)).Has("key") // will not panic
	_ = ((*Age)(nil)).IsNil()       // will not panic

	// This following line will panic. But the
	// panic is not caused by invoking the method.
	// It is caused by the nil pointer dereference
	// within the method body.
	((*Age)(nil)).Increase()
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Receiver Arguments Are Passed by Copy
</h3>
<p></p>
<div class="tmd-usual">
Same as general function arguments, the receiver arguments are also passed by copy. So, the modifications on the <a href="value-part.html">direct part</a> of a receiver argument in a method call will not be reflected to the outside of the method.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

type Book struct {
	pages int
}

func (b Book) SetPages(pages int) {
	b.pages = pages
}

func main() {
	var b Book
	b.SetPages(123)
	fmt.Println(b.pages) // 0
}
</code></pre>
<p></p>
<div class="tmd-usual">
Another example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

type Book struct {
	pages int
}

type Books []Book

func (books Books) Modify() {
	// Modifications on the underlying part of
	// the receiver will be reflected to outside
	// of the method.
	books[0].pages = 500
	// Modifications on the direct part of the
	// receiver will not be reflected to outside
	// of the method.
	books = append(books, Book{789})
}

func main() {
	var books = Books{{123}, {456}}
	books.Modify()
	fmt.Println(books) // [{500} {456}]
}
</code></pre>
<p></p>
<div class="tmd-usual">
Some off topic, if the two lines in the orders of the above <code class="tmd-code-span">Modify</code> method are exchanged, then both of the modifications will not be reflected to outside of the method body.
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func (books Books) Modify() {
	books = append(books, Book{789})
	books[0].pages = 500
}

func main() {
	var books = Books{{123}, {456}}
	books.Modify()
	fmt.Println(books) // [{123} {456}]
}
</code></pre>
<p></p>
<div class="tmd-usual">
The reason here is that the <code class="tmd-code-span">append</code> call will allocate a new memory block to store the elements of the copy of the passed slice receiver argument. The allocation will not reflect to the passed slice receiver argument itself.
</div>
<p></p>
<div class="tmd-usual">
To make both of the modifications be reflected to outside of the method body, the receiver of the method must be a pointer one.
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func (books *Books) Modify() {
	*books = append(*books, Book{789})
	(*books)[0].pages = 500
}

func main() {
	var books = Books{{123}, {456}}
	books.Modify()
	fmt.Println(books) // [{500} {456} {789}]
}
</code></pre>
<p></p>
<h3 id="method-value-Normalization" class="tmd-header-3">
Method Value Normalization
</h3>
<p></p>
<div class="tmd-usual">
At compile time, compilers will normalize each method value expression, by changing implicit address taking and pointer dereference operations into explicit ones in that method value expression.
</div>
<p></p>
<div class="tmd-usual">
Assume <code class="tmd-code-span">v</code> is a value of type <code class="tmd-code-span">T</code> and <code class="tmd-code-span">v.m</code> is a legal method value expression,
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
if <code class="tmd-code-span">m</code> is a method explicitly declared for type <code class="tmd-code-span">*T</code>, then compilers will normalize it as <code class="tmd-code-span">(&amp;v).m</code>;
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
if <code class="tmd-code-span">m</code> is a method explicitly declared for type <code class="tmd-code-span">T</code>, then the method value expression <code class="tmd-code-span">v.m</code> is already normalized.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
Assume <code class="tmd-code-span">p</code> is a value of type <code class="tmd-code-span">*T</code> and <code class="tmd-code-span">p.m</code> is a legal method value expression,
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
if <code class="tmd-code-span">m</code> is a method explicitly declared for type <code class="tmd-code-span">T</code>, then compilers will normalize it as <code class="tmd-code-span">(*p).m</code>;
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
if <code class="tmd-code-span">m</code> is a method explicitly declared for type <code class="tmd-code-span">*T</code>, then the method value expression <code class="tmd-code-span">p.m</code> is already normalized.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
Promoted method value Normalization will be explained in the following <a href="type-embedding.html#method-value-evaluation">type embedding</a> article.
</div>
<p></p>
<p></p>
<h3 id="method-value-evaluation" class="tmd-header-3">
Method Value Evaluation
</h3>
<p></p>
<div class="tmd-usual">
Assume <code class="tmd-code-span">v.m</code> is a normalized method value expression, at run time, when the method value <code class="tmd-code-span">v.m</code> is evaluated, the receiver argument <code class="tmd-code-span">v</code> is evaluated and a copy of the evaluation result is saved and used in later calls to the method value.
</div>
<p></p>
<div class="tmd-usual">
For example, in the following code,
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
the method value expression <code class="tmd-code-span">b.Pages</code> is already normalized. At run time, a copy of the receiver argument <code class="tmd-code-span">b</code> is saved. The copy is the same as <code class="tmd-code-span">Book{pages: 123}</code>, the subsequent modification of value <code class="tmd-code-span">b</code> has no effects on this copy. That is why the call <code class="tmd-code-span">f1()</code> prints <code class="tmd-code-span">123</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
the method value expression <code class="tmd-code-span">p.Pages</code> is normalized as <code class="tmd-code-span">(*p).Pages</code> at compile time. At run time, the receiver argument <code class="tmd-code-span">*p</code> is evaluated to the current <code class="tmd-code-span">b</code> value, which is <code class="tmd-code-span">Book{pages: 123}</code>. A copy of the evaluation result is saved and used in later calls of the method value, that is why the call <code class="tmd-code-span">f2()</code> also prints <code class="tmd-code-span">123</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
the method value expression <code class="tmd-code-span">p.Pages2</code> is already normalized. At run time, a copy of the receiver argument <code class="tmd-code-span">p</code> is saved. The saved value is the address of the value <code class="tmd-code-span">b</code>, thus any changes to <code class="tmd-code-span">b</code> will be reflected through dereferencing of the saved value, that is why the call <code class="tmd-code-span">g1()</code> prints <code class="tmd-code-span">789</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
the method value expression <code class="tmd-code-span">b.Pages2</code> is normalized as <code class="tmd-code-span">(&amp;b).Pages2</code> at compile time. At run time, a copy of the evaluation result of <code class="tmd-code-span">&amp;b</code> is saved. The saved value is the address of the value <code class="tmd-code-span">b</code>, thus any changes to <code class="tmd-code-span">b</code> will be reflected through dereferencing of the saved value, that is why the call <code class="tmd-code-span">g2()</code> prints <code class="tmd-code-span">789</code>.
</div>
</li>
</ul>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

type Book struct {
	pages int
}

func (b Book) Pages() int {
	return b.pages
}

func (b *Book) Pages2() int {
	return (*b).Pages()
}

func main() {
	var b = Book{pages: 123}
	var p = &amp;b
	var f1 = b.Pages
	var f2 = p.Pages
	var g1 = p.Pages2
	var g2 = b.Pages2
	b.pages = 789
	fmt.Println(f1()) // 123
	fmt.Println(f2()) // 123
	fmt.Println(g1()) // 789
	fmt.Println(g2()) // 789
}
</code></pre>
<p></p>
<h3 id="method-obtaining" class="tmd-header-3">
A Defined Type Doesn't Obtain the Methods Declared Explicitly for the Source Type Used in Its Definition
</h3>
<p></p>
<div class="tmd-usual">
For example, in the following code, unlike the defined type <code class="tmd-code-span">MyInt</code>, the defined type <code class="tmd-code-span">Age</code> has not an <code class="tmd-code-span">IsOdd</code> method.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

type MyInt int
func (mi MyInt) IsOdd() bool {
	return mi%2 == 1
}

type Age MyInt

func main() {
	var x MyInt = 3
	_ = x.IsOdd() // okay
	
	var y Age = 36
	// _ = y.IsOdd() // error: y.IsOdd undefined
	_ = y
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Should a Method Be Declared With Pointer Receiver or Value Receiver?
</h3>
<p></p>
<div class="tmd-usual">
Firstly, from the last section, we know that sometimes we must declare methods with pointer receivers.
</div>
<p></p>
<div class="tmd-usual">
In fact, we can always declare methods with pointer receivers without any logic problems. It is just a matter of program performance that sometimes it is better to declare methods with value receivers.
</div>
<p></p>
<div class="tmd-usual">
For the cases value receivers and pointer receivers are both acceptable, here are some factors needed to be considered to make decisions.
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
Too many pointer copies may cause heavier workload for garbage collector.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
If the size of a value receiver type is large, then the receiver argument copy cost may be not negligible. Pointer types are all <a href="value-copy-cost.html">small-size</a> types.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
Declaring methods of both value receivers and pointer receivers for the same base type is more likely to cause data races if the declared methods are called concurrently in multiple goroutines.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
Values of the types in the <code class="tmd-code-span">sync</code> standard package should not be copied, so declaring methods with value receivers for struct types which <a href="type-embedding.html">embedding</a> the types in the <code class="tmd-code-span">sync</code> standard package is problematic.
</div>
</li>
</ul>
<p></p>
<p></p>
<div class="tmd-usual">
If it is hard to make a decision whether a method should use a pointer receiver or a value receiver, then just choose the pointer receiver way.
</div>
</div>
